<script setup lang="ts">
import {
    EAnimateCSSUtil,
    EAvatar,
    EButton,
    ECube,
    EMediaQueryUtil,
    ESelect,
} from 'exploria-ui';
import { useSystemStore } from '@/stores/systemStore.ts';
import { ThemeEnum } from '@/types/global.d';
import html2canvas from 'html2canvas';
import { nextTick, onMounted, onUnmounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';

const router = useRouter();
const systemStore = useSystemStore();
defineProps<{
    backButton?: boolean;
    more?: boolean;
}>();
const emit = defineEmits<{
    (e: 'back'): void;
    (e: 'update:more', value: boolean): void;
}>();

const position = {
    x: 0,
    y: 0,
};

let lastCanvas: HTMLCanvasElement | null = null;
let id = 0;

const updatePosition = (e: MouseEvent) => {
    position.x = e.clientX;
    position.y = e.clientY;
};

onMounted(() => {
    window.addEventListener('mousedown', updatePosition);
});
onUnmounted(() => {
    window.removeEventListener('mousedown', updatePosition);
});

const shadowColorMap = {
    [ThemeEnum.LIGHT]: 'rgb(204,82,232)',
    [ThemeEnum.DARK]: 'rgb(237,136,136)',
    [ThemeEnum.PLAIN]: 'rgb(58,58,58)',
} as Record<ThemeEnum, string>;

const startAnimation = (theme: ThemeEnum) => {
    if (theme === systemStore.currentTheme) return;
    lastCanvas?.remove();
    cancelAnimationFrame(id);
    html2canvas(document.body, {
        x: 0, // 起始横坐标
        y: 0, // 起始纵坐标
        width: window.innerWidth, // 截取宽度
        height: window.innerHeight, // 截取高度
    }).then((canvas) => {
        systemStore.currentTheme = theme;
        nextTick(() => {
            lastCanvas = canvas;
            canvas.style.position = 'fixed';
            canvas.style.zIndex = '3000';
            canvas.style.inset = '0';
            canvas.style.pointerEvents = 'none';
            // 阴影
            canvas.style.filter = `drop-shadow(0 0 10px ${shadowColorMap[theme]})`;
            document.body.appendChild(canvas);
            const ctx = canvas.getContext('2d')!;
            // 画一个圆并使圆的背景色透明
            ctx.globalCompositeOperation = 'destination-out'; // 把接下来画的内容“抠掉”

            let r = 0;
            const maxR = Math.sqrt(
                window.innerHeight ** 2 + window.innerWidth ** 2,
            );

            const loop = () => {
                r += 20;
                if (r > maxR) {
                    canvas.remove();
                    lastCanvas = null;
                    cancelAnimationFrame(id);
                    return;
                }
                ctx.beginPath();
                ctx.arc(position.x, position.y, r, 0, Math.PI * 2);
                ctx.fill();
                id = requestAnimationFrame(loop);
            };
            loop();
        });
    });
};

const { locale } = useI18n();

const changeLocale = (value: 'zhCN' | 'en') => {
    systemStore.currentLocale = value;
    locale.value = value;
};
const mounted = (e: CustomEvent) => {
    const target = e.target as HTMLDivElement;
    // TODO bug target = null
    console.log(target);
    target && EAnimateCSSUtil.once(target, 'animate__bounce');
};
</script>

<template>
    <div class="header" ref="header">
        <div class="left">
            <EButton @click="emit('back')" v-if="backButton"> 返回</EButton>

            <template v-else>
                <span
                    class="header-iconfont"
                    v-if="
                        EMediaQueryUtil.is('phone') &&
                        router.currentRoute.value.path.includes('/document')
                    "
                    :class="more ? 'icon-zhedie-shouqi' : 'icon-zhedie-zhankai'"
                    @click="emit('update:more', !more)"
                />
                <template v-else>
                    <ECube title="立方体" />
                    <div class="title" @vue:mounted="mounted">Exploria UI</div>
                </template>
            </template>

            <slot />
        </div>
        <div class="right">
            <EAvatar
                src="/author_avatar.png"
                title="作者"
                @click="router.push({ name: 'author' })"
            />

            <template v-if="!EMediaQueryUtil.is('phone')">
                <!-- 主题 -->
                <ESelect
                    :model-value="systemStore.currentTheme"
                    :items="[
                        {
                            label: '浅色',
                            value: ThemeEnum.LIGHT,
                        },
                        {
                            label: '深色',
                            value: ThemeEnum.DARK,
                        },
                        {
                            label: '朴素',
                            value: ThemeEnum.PLAIN,
                        },
                        {
                            label: '手机',
                            value: ThemeEnum.PHONE,
                        },
                    ]"
                    @update:model-value="(theme) => startAnimation(theme)"
                />

                <ESelect
                    :model-value="systemStore.currentLocale"
                    :items="[
                        {
                            label: '中文',
                            value: 'zhCN',
                        },
                        {
                            label: '英文',
                            value: 'en',
                        },
                    ]"
                    @update:model-value="
                        (locale) => changeLocale(locale as 'zhCN' | 'en')
                    "
                />
            </template>

            <RouterLink
                :to="{ name: 'home' }"
                v-if="router.currentRoute.value.name !== 'home'"
            >
                指南
            </RouterLink>
            <RouterLink
                :to="{ name: 'basic.button' }"
                v-if="!router.currentRoute.value.path.includes('/document')"
            >
                组件
            </RouterLink>
        </div>
    </div>
</template>

<style scoped lang="scss">
@use '@/style/global' as global;
@import 'iconfont/iconfont.css';

.header {
    height: global.$header-height;
    position: sticky;
    top: 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    font-size: 20px;
    padding: 0 27px;

    .left {
        display: flex;
        align-items: center;
        gap: 15px;
    }

    .right {
        margin-left: auto;
        display: flex;
        flex-direction: row;
        align-items: center;
        gap: 20px;

        .one-avatar {
            $size: 40px;
            width: $size;
            height: $size;
        }

        .e-select {
            background-color: rgba(255, 255, 255, 0.5);

            :deep(.e-select-option-list) {
                background-color: rgba(255, 255, 255, 0.8);
            }
        }

        a {
            color: #000;
            text-decoration: none;
            font-size: 15px;
            white-space: nowrap;

            &:hover {
                color: #409eff;
            }
        }
    }
}
</style>
